# 1.数据加载与预处理：
import numpy as np
import torch
torch.manual_seed(10)
# 确保数据文件'data-02-stock_daily.csv'存在且格式正确（即每行有至少5个由逗号分隔的数值）。

# 正确读取数据，包括处理可能的数据类型转换问题（如字符串到浮点数的转换）。
data = np.loadtxt('data-02-stock_daily.csv',delimiter=',')
print(data)
# 数据反转应该是合理的，取决于数据的时间顺序和预测任务的需求。
data = data[::-1]
# MinMaxScaler应正确应用于整个数据集，以标准化特征。
from sklearn.preprocessing import MinMaxScaler
data = MinMaxScaler().fit_transform(data)
# 2.特征与目标生成：
# 目标变量 y_binary 的生成逻辑（int(i[4] > i[0])）应明确反映预测任务的需求（例如，可能是判断收盘价是否高于开盘价）。
y_binary = []
for i in data:
    y_binary.append(int(i[4] > i[0]))
# 特征集 x 的生成应考虑窗口大小 c 的选择是否合适，以及是否覆盖了所有可能的数据点（除了最后的 c-1 个）。
c = 7
x = []
y = []
for i in range(len(data) - c):
    x.append(data[i:i+c])
    y.append(y_binary[i+c])
x = torch.Tensor(x)
y = torch.Tensor(y).reshape(-1,1)
# 3.PyTorch模型与训练：
# 模型定义应匹配输入数据的特征数量（这里是 35，假设每个时间窗口包含7个时间步，每个时间步有5个特征，但请根据实际数据结构验证）。
model = torch.nn.Sequential(
    torch.nn.Linear(in_features=35,out_features=1),
    torch.nn.Sigmoid()
)
# 使用 BCELoss 作为损失函数是合理的，前提是这是一个二分类问题。
loss_fn = torch.nn.BCELoss()
# 优化器（RMSprop）和学习率（默认为 0.01）的选择应适合问题。
op = torch.optim.RMSprop(params=model.parameters(),lr=0.01)
# 训练循环应确保整个训练集在每个epoch中被遍历，尽管这里使用了固定次数的迭代（20000次）。更常见的做法是使用epoch来迭代整个数据集。
# 损失应逐渐减小，表明模型正在学习。
from sklearn.model_selection import train_test_split
train_x,test_x,train_y,test_y=train_test_split(x,y,shuffle=False)
for i in range(20000):
    op.zero_grad()
    h = model(train_x.reshape(-1,35))
    loss = loss_fn(h,train_y)
    loss.backward()
    op.step()
    print(loss)
# 4.模型评估：
# 使用二分类阈值（0.5）将模型输出转换为类别标签是合理的。
predict = model(test_x.reshape(-1,35))
y_predict = (predict > 0.5).float()
# 准确率（accuracy）作为评估指标在二分类问题中是常见的，但应确保它正确计算。
acc = (y_predict == test_y).float().mean()
print(acc)
# 5.代码健壮性与错误处理：
# 确保在训练模型之前，所有必要的库都已正确导入，且版本兼容。
# 6.可重复性与透明度：
# 设置随机种子（如果适用）以确保结果的可重复性。
# 注释代码以解释每个步骤的目的和逻辑。
# 7.版本控制和文档：
# 确保学生使用git正确上传代码，包括所有必要的文件。
